package com.yupi.springbootinit.statemachine.config;

import com.yupi.springbootinit.statemachine.core.StateMachine;
import com.yupi.springbootinit.statemachine.core.StateProcessor;
import com.yupi.springbootinit.statemachine.enums.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 状态机配置类
 * 在应用启动时初始化所有状态转换规则
 */
@Slf4j
@Component
public class StateMachineConfig implements CommandLineRunner {
    
    @Autowired
    private StateMachine stateMachine;

    @Autowired(required = false)
    private java.util.List<StateProcessor<?, ?>> stateProcessorBeans;
    
    @Override
    public void run(String... args) throws Exception {

        // 初始化订单状态转换规则
        initOrderStateTransitions();
        
        // 初始化工艺单状态转换规则
        initProcessSheetStateTransitions();
        
        // 初始化生产排期状态转换规则
        initProductionScheduleStateTransitions();
        
        // 初始化工序实例状态转换规则
        initProcessInstanceStateTransitions();
        
        // 初始化生产工单状态转换规则
        initProductionOrderStateTransitions();
        
        // 初始化质检任务状态转换规则
        initQualityInspectionStateTransitions();
        
        // 注册所有状态处理器到引擎
        if (stateProcessorBeans != null) {
            for (StateProcessor<?, ?> processor : stateProcessorBeans) {
                stateMachine.registerProcessor(processor);
            }
            log.info("已注册状态处理器数量: {}", stateProcessorBeans.size());
        } else {
            log.warn("未发现可注册的状态处理器Bean");
        }
        

    }
    
    /**
     * 初始化订单状态转换规则
     * 订单：已创建 → 工艺已发布 → 排期已发布 → 生产中 → 检验中 → 已完成
     */
    private void initOrderStateTransitions() {
        String stateType = "ORDER";
        
        // 已创建 → 工艺已发布
        stateMachine.registerTransition(stateType, 
            OrderStateEnum.CREATED.getCode(), 
            List.of(OrderStateEnum.ROUTING_PUBLISHED.getCode()));
        
        // 工艺已发布 → 排期已发布
        stateMachine.registerTransition(stateType, 
            OrderStateEnum.ROUTING_PUBLISHED.getCode(), 
            List.of(OrderStateEnum.SCHEDULE_PUBLISHED.getCode()));
        
        // 排期已发布 → 生产中
        stateMachine.registerTransition(stateType, 
            OrderStateEnum.SCHEDULE_PUBLISHED.getCode(), 
            List.of(OrderStateEnum.PRODUCING.getCode()));
        
        // 生产中 → 检验中
        stateMachine.registerTransition(stateType, 
            OrderStateEnum.PRODUCING.getCode(), 
            List.of(OrderStateEnum.INSPECTING.getCode()));
        
        // 检验中 → 已完成
        stateMachine.registerTransition(stateType, 
            OrderStateEnum.INSPECTING.getCode(), 
            List.of(OrderStateEnum.COMPLETED.getCode()));
    }
    
    /**
     * 初始化工艺单状态转换规则
     * 工艺单：草稿 → 已发布（已变更）
     */
    private void initProcessSheetStateTransitions() {
        String stateType = "PROCESS_SHEET";
        
        // 草稿 → 已发布
        stateMachine.registerTransition(stateType, 
            ProcessSheetStateEnum.DRAFT.getCode(), 
            List.of(ProcessSheetStateEnum.PUBLISHED.getCode()));
        
        // 已发布 → 已变更
        stateMachine.registerTransition(stateType, 
            ProcessSheetStateEnum.PUBLISHED.getCode(), 
            List.of(ProcessSheetStateEnum.CHANGED.getCode()));
        
        // 已变更 → 已发布（重新发布）
        stateMachine.registerTransition(stateType, 
            ProcessSheetStateEnum.CHANGED.getCode(), 
            List.of(ProcessSheetStateEnum.PUBLISHED.getCode()));
    }
    
    /**
     * 初始化生产工单状态转换规则
     * 工单：未开始 → 进行中 → 暂停/异常 → 已完成
     */
    private void initProductionOrderStateTransitions() {
        String stateType = "PRODUCTION_ORDER";
        
        // 未开始 → 进行中
        stateMachine.registerTransition(stateType, 
            ProductionOrderStateEnum.NOT_STARTED.getCode(), 
            List.of(ProductionOrderStateEnum.IN_PROGRESS.getCode()));
        
        // 进行中 → 暂停/异常/已完成
        stateMachine.registerTransition(stateType, 
            ProductionOrderStateEnum.IN_PROGRESS.getCode(), 
            List.of(
                ProductionOrderStateEnum.PAUSED.getCode(),
                ProductionOrderStateEnum.EXCEPTION.getCode(),
                ProductionOrderStateEnum.COMPLETED.getCode()
            ));
        
        // 暂停 → 进行中
        stateMachine.registerTransition(stateType, 
            ProductionOrderStateEnum.PAUSED.getCode(), 
            List.of(ProductionOrderStateEnum.IN_PROGRESS.getCode()));
        
        // 异常 → 进行中
        stateMachine.registerTransition(stateType, 
            ProductionOrderStateEnum.EXCEPTION.getCode(), 
            List.of(ProductionOrderStateEnum.IN_PROGRESS.getCode()));
    }
    
    /**
     * 初始化质检任务状态转换规则
     * 质检任务：待检验 → 检验中 → 检验合格/不合格 → 已完成
     */
    private void initQualityInspectionStateTransitions() {
        String stateType = "QUALITY_INSPECTION";
        
        // 待检验 → 检验中
        stateMachine.registerTransition(stateType, 
            QualityInspectionStateEnum.PENDING.getCode(), 
            List.of(QualityInspectionStateEnum.IN_PROGRESS.getCode()));
        
        // 检验中 → 检验合格/不合格
        stateMachine.registerTransition(stateType, 
            QualityInspectionStateEnum.IN_PROGRESS.getCode(), 
            List.of(
                QualityInspectionStateEnum.QUALIFIED.getCode(),
                QualityInspectionStateEnum.UNQUALIFIED.getCode()
            ));
        
        // 检验合格 → 已完成
        stateMachine.registerTransition(stateType, 
            QualityInspectionStateEnum.QUALIFIED.getCode(), 
            List.of(QualityInspectionStateEnum.COMPLETED.getCode()));
        
        // 检验不合格 → 已完成（记录不合格结果）
        stateMachine.registerTransition(stateType, 
            QualityInspectionStateEnum.UNQUALIFIED.getCode(), 
            List.of(QualityInspectionStateEnum.COMPLETED.getCode()));
    }
    
    /**
     * 初始化生产排期状态转换规则
     * 排期：编辑中 → 已发布 → 已调整
     */
    private void initProductionScheduleStateTransitions() {
        String stateType = "PRODUCTION_SCHEDULE";
        
        // 编辑中 → 已发布
        stateMachine.registerTransition(stateType, 
            ProductionScheduleStateEnum.EDITING.getCode(), 
            List.of(ProductionScheduleStateEnum.PUBLISHED.getCode()));
        
        // 已发布 → 已调整
        stateMachine.registerTransition(stateType, 
            ProductionScheduleStateEnum.PUBLISHED.getCode(), 
            List.of(ProductionScheduleStateEnum.ADJUSTED.getCode()));
        
        // 已调整 → 已发布（重新发布）
        stateMachine.registerTransition(stateType, 
            ProductionScheduleStateEnum.ADJUSTED.getCode(), 
            List.of(ProductionScheduleStateEnum.PUBLISHED.getCode()));
    }
    
    /**
     * 初始化工序实例状态转换规则
     * 工序：待开始 → 进行中 → 待检验 → 检验中 → 不合格(返工)/已完成
     */
    private void initProcessInstanceStateTransitions() {
        String stateType = "PROCESS_INSTANCE";
        
        // 待开始 → 进行中
        stateMachine.registerTransition(stateType, 
            ProcessInstanceStateEnum.PENDING.getCode(), 
            List.of(ProcessInstanceStateEnum.IN_PROGRESS.getCode()));
        
        // 进行中 → 待检验/已完成（无需检验的工序直接完成）
        stateMachine.registerTransition(stateType, 
            ProcessInstanceStateEnum.IN_PROGRESS.getCode(), 
            List.of(
                ProcessInstanceStateEnum.PENDING_INSPECTION.getCode(),
                ProcessInstanceStateEnum.COMPLETED.getCode()
            ));
        
        // 待检验 → 检验中
        stateMachine.registerTransition(stateType, 
            ProcessInstanceStateEnum.PENDING_INSPECTION.getCode(), 
            List.of(ProcessInstanceStateEnum.INSPECTING.getCode()));
        
        // 检验中 → 不合格(返工)/已完成
        stateMachine.registerTransition(stateType, 
            ProcessInstanceStateEnum.INSPECTING.getCode(), 
            List.of(
                ProcessInstanceStateEnum.REJECTED.getCode(),
                ProcessInstanceStateEnum.COMPLETED.getCode()
            ));
        
        // 不合格(返工) → 进行中（重新开始工序）
        stateMachine.registerTransition(stateType, 
            ProcessInstanceStateEnum.REJECTED.getCode(), 
            List.of(ProcessInstanceStateEnum.IN_PROGRESS.getCode()));
    }
}